package com.zz.yt.lib.login.badge;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;

import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.NotificationUtils;
import com.whf.android.jar.app.Latte;
import com.whf.android.jar.util.log.LatteLogger;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import me.leolin.shortcutbadger.ShortcutBadger;

import static android.content.Context.NOTIFICATION_SERVICE;


/**
 * 角标
 *
 * @author qf
 */
public final class BadgeUtils implements BadgeKeys {

    /*** 上次设置角标的值 */
    private int tidings = -1;

    /**
     * 启动activity的完整路径
     */
    private String launcherClassName;

    /**
     * 点击通知跳转的activity
     */
    private Class mClass;

    /**
     * 上下文对象
     */
    private final Context context;

    /**
     * 是否开启角标的日志
     */
    private boolean isBug = true;

    /**
     * 小米的通知栏标题
     */
    private String contentTitle = "您有新的消息";

    /**
     * 小米的通知栏内容
     */
    private String contentText = "点按即可返回应用";

    private static class Holder {
        @SuppressLint("StaticFieldLeak")
        private static final BadgeUtils INSTANCE = new BadgeUtils(Latte.getApplicationContext());
    }

    /**
     * 下面是为了解决序列化反序列化破解单例模式
     */
    private Object readResolve() {
        return Holder.INSTANCE;
    }

    @NotNull
    public static BadgeUtils Bundle(Class cla) {
        return Holder.INSTANCE.setClass(cla);
    }

    private BadgeUtils(Context context) {
        this.context = context;
    }

    /**
     * @param cla :小米的通知栏标题
     */
    private BadgeUtils setClass(@NonNull Class cla) {
        this.mClass = cla;
        this.launcherClassName = cla.getName();
        LatteLogger.i(launcherClassName);
        return this;
    }


    /**
     * @param title :小米的通知栏标题
     */
    public BadgeUtils setContentTitle(String title) {
        this.contentTitle = title;
        return this;
    }

    /**
     * @param text：小米的通知栏内容
     */
    public BadgeUtils setContentText(String text) {
        this.contentText = text;
        return this;
    }

    /**
     * @param bug:是否开启角标的日志
     */
    public BadgeUtils setBug(boolean bug) {
        isBug = bug;
        return this;
    }

    public void init(int count) {
        String model = DeviceUtils.getManufacturer();
        if (TextUtils.isEmpty(model)) {
            return;
        }
        int number = Math.max(0, Math.min(count, 99));
        if (isBug) {
            LatteLogger.i("model=" + model + ";number=" + number);
        }
        try {
            if (XI_MI.equals(model) || tidings != number) {
                //如果是小米或值改变，刷新角标.
                tidings = number;
                switch (model) {
                    case HONOR:
                    case HUO_WEI:
                    case HUO_WEI_1:
                        setHuaWeiBadge(number);
                        break;
                    case XI_MI:
                    case RED_MI:
                        setXiMiBadge(number);
                        break;
                    case VI_VO:
                    case IQOO:
                        setViVoBadge(number);
                        break;
                    case OP_PO:
                    case REAL_ME:
                    case ONE_PLUS:
                        setOppOBadge(number);
                        break;
                    case SAM_SUNG:
                    case SAM_SUNG_1:
                        setSamSungBadge(number);
                        break;
                    case MEI_ZU:
                    case MEI_ZU_1:
                        setMeiZuBadge(number);
                        break;
                    case LENOVO:
                        setZukBadge(number);
                        break;
                    case HTC:
                        setHTCBadge(number);
                        break;
                    case SONY:
                    default:
                        ShortcutBadger.applyCount(context, number);
                        break;
                }
            }
        } catch (Exception e) {
            LatteLogger.e("手机不支持角标：" + e.getMessage());
        }
    }

    /***
     * 华为角标
     * @param number：
     */
    private void setHuaWeiBadge(int number) {
        //需要存储的数据
        Bundle localBundle = new Bundle();
        //包名
        localBundle.putString("package", Latte.getApplicationContext().getPackageName());
        localBundle.putString("class", launcherClassName);
        //未读信息条数
        localBundle.putInt("badgenumber", number);
        Latte.getActivity().getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"),
                "change_badge", null, localBundle);
    }

    /***
     * 小米角标
     * @param number：
     */
    @SuppressLint("UnspecifiedImmutableFlag")
    private void setXiMiBadge(int number) {
        //小米角标,需要清空之前的角标重新设值。
        NotificationUtils.cancelAll();
        if (number == 0) {
            return;
        }
        NotificationManager manager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
        //Android 8.0 以上需包添加渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                    CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(true); //是否在桌面icon右上角展示小红点
            channel.setLightColor(Color.RED); //小红点颜色
            channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
            manager.createNotificationChannel(channel);
        }

        Intent appIntent = new Intent(context, mClass);
        appIntent.setAction(Intent.ACTION_MAIN);
        appIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);//关键的一步，设置启动模式
        PendingIntent contentIntent;
        Notification notification;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            contentIntent = PendingIntent.getActivity(context, 0,
                    appIntent, PendingIntent.FLAG_IMMUTABLE);
            notification = new Notification.Builder(context, CHANNEL_ID)
                    .setTicker("新消息") //通知首次出现在通知栏，带上升动画效果的
                    .setContentIntent(contentIntent)
                    .setSmallIcon(Latte.getAppIcon())
                    .setLargeIcon(Latte.getAppLarge())
                    .setContentTitle(contentTitle)
                    .setContentText(contentText)
                    .setNumber(number)
                    .build();
        } else {
            contentIntent = PendingIntent.getActivity(context, 0,
                    appIntent, PendingIntent.FLAG_ONE_SHOT);
            notification = new NotificationCompat.Builder(context, CHANNEL_ID)
                    .setPriority(Notification.PRIORITY_DEFAULT) //设置该通知优先级
                    .setTicker("新消息") //通知首次出现在通知栏，带上升动画效果的
                    .setContentIntent(contentIntent)
                    .setSmallIcon(Latte.getAppIcon())
                    .setLargeIcon(Latte.getAppLarge())
                    .setContentTitle(contentTitle)
                    .setContentText(contentText)
                    .build();
        }

        // 小米设置角标
        try {
            Field field = notification.getClass().getDeclaredField("extraNotification");
            Object extraNotification = field.get(notification);
            if (extraNotification != null) {
                Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
                method.invoke(extraNotification, number);
                Method method2 = extraNotification.getClass().getDeclaredMethod("messageCount", int.class);
                method2.invoke(extraNotification, number);
            }
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
        }

        //清除之前角标
        NotificationUtils.cancel(100);
        //设置现在角标
        manager.notify(100, notification);
    }

    /***
     * vivo角标
     * <p>vivo之前是不开放角标的，现在官方文档里开放了角标并且提供了对应的方法，与华为用法差不多，不过存在一定的限制条件。
     * <p>一、不能使用vivo自身的推送渠道，
     * <p>二、手机需要8.0及以上的Android版本。
     * <p>官方文档中提示8.0以上版本需要添加flag
     * <p>intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);(@hide修饰的，外部无法调用)
     * @param number：
     */
    private void setViVoBadge(int number) {
        Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
        intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
        intent.putExtra("packageName", Latte.getApplicationContext().getPackageName());
        intent.putExtra("className", launcherClassName);
        intent.putExtra("notificationNum", number);
        context.sendBroadcast(intent);
    }

    /**
     * 设置oppo的Badge :oppo角标提醒目前只针对内部软件还有微信、QQ开放，其他的暂时无法提供
     */
    private void setOppOBadge(int number) {
        try {
            Bundle extras = new Bundle();
            extras.putInt("app_badge_count", number);
            context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"),
                    "setAppBadgeCount", String.valueOf(number), extras);
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
            setRealMe(number);
        }
    }

    /**
     * 设置oppo的Badge :oppo角标提醒目前只针对内部软件还有微信、QQ开放，其他的暂时无法提供
     */
    private void setRealMe(int number) {
        try {
            Intent intent = new Intent("com.oppo.unsettledevent");
            intent.putExtra("packageName", launcherClassName);
            intent.putExtra("number", number);
            intent.putExtra("upgradeNumber", number);
            context.sendBroadcast(intent);
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
        }
    }

    /***
     * 三星角标
     * @param number：
     */
    private void setSamSungBadge(int number) {
        Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
        intent.putExtra("badge_count", number);
        intent.putExtra("badge_count_package_name", Latte.getApplicationContext().getPackageName());
        intent.putExtra("badge_count_class_name", launcherClassName);
        context.sendBroadcast(intent);
    }

    /***
     * 魅族角标
     * @param number：
     */
    private void setMeiZuBadge(int number) {
        try {
            final Bundle extra = new Bundle();
            //包名
            extra.putString("package", Latte.getApplicationContext().getPackageName());
            //类名
            extra.putString("class", launcherClassName);
            //红点角标数量
            extra.putInt("badge_number", number);
            //修改红点角标数量的方法名
            final String authority = "com.meizu.flyme.launcher.app_extras";
            final Uri contentUri = Uri.parse("content://" + authority + "/badge_extras");
            context.getContentResolver().call(contentUri, "change_badge", null, extra);
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
            ShortcutBadger.applyCount(context, number);
        }
    }

    /***
     * 联想ZUK（支持）
     * @param number：
     */
    private void setZukBadge(int number) {
        //修改红点角标数量的方法名
        final String authority = "com.android.badge";
        try {
            Bundle extra = new Bundle();
            //包名
            extra.putString("package", Latte.getApplicationContext().getPackageName());
            //类名
            extra.putString("class", launcherClassName);
            extra.putInt("app_badge_count", number);
            Uri contentUri = Uri.parse("content://" + authority + "/badge");
            context.getContentResolver().call(contentUri, "setAppBadgeCount", null, extra);
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
        }
    }

    /***
     * HTC（支持）
     * @param number：
     */
    private void setHTCBadge(int number) {
        try {
            Intent intent1 = new Intent("com.htc.launcher.action.SET_NOTIFICATION");
            intent1.putExtra("com.htc.launcher.extra.COMPONENT", Latte.getApplicationContext().getPackageName());
            intent1.putExtra("com.htc.launcher.extra.COUNT", number);
            context.sendBroadcast(intent1);

            Intent intent2 = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");
            intent2.putExtra("packagename", Latte.getApplicationContext().getPackageName());
            intent2.putExtra("count", number);
            context.sendBroadcast(intent2);

        } catch (Exception e) {
            LogUtils.e(e.getMessage());
        }
    }


}
